package br.com.tarcilahelpdesk.managedBeans;

import br.com.tarcilahelpdesk.enums.EnumObjetosPersistentes;
import br.com.tarcilahelpdesk.enums.EnumTipoAtributo;
import br.com.tarcilahelpdesk.enums.EnumTipoChamado;
import br.com.tarcilahelpdesk.modelo.Modelo;
import br.com.tarcilahelpdesk.persistencia.AtributoValor;
import br.com.tarcilahelpdesk.util.HibernateUtil;
import java.io.Serializable;
import java.util.Collection;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
import javax.faces.context.FacesContext;
import javax.faces.model.SelectItem;
import org.hibernate.Session;
import org.hibernate.exception.ConstraintViolationException;
import org.primefaces.model.LazyDataModel;

/**
 * MB da janela de CRUD.
 * @author vinicius
 */
@ManagedBean(name = "crud")
@ViewScoped
public class CrudBean implements Serializable
{

    private Session ss;
    private LazyDataModel<AtributoValor> tabela;
    private String nomeAtributo;
    private EnumTipoAtributo tipoAtributo;
    private String msgPainelPrincipal;
    private AtributoValor atributoSelecionado;
    private EnumObjetosPersistentes objetoEnum;
    private EnumTipoChamado tipoChamadoEnum;
    private boolean exibirPainelNome;

    /**
     * Construtor - Abre a sessao do hibernate.
     */
    public CrudBean()
    {
        ss = HibernateUtil.getSessionFactory().openSession();
    }

    /**
     * Incializa o bean com os argumentos passados na flash.
     */
    @PostConstruct
    public void inicializar()
    {

        if (FacesContext.getCurrentInstance().getExternalContext().getFlash().containsKey("objetoPersistente"))
        {
            setObjetoEnum((EnumObjetosPersistentes) FacesContext.getCurrentInstance().getExternalContext().getFlash().get("objetoPersistente"));
            setMsgPainelPrincipal("Cadastrar Atributos de " + getObjetoEnum().name());
            tabela = Modelo.getInstancia().gerarLazyModelAtributos(objetoEnum, ss);
        }
        if (FacesContext.getCurrentInstance().getExternalContext().getFlash().containsKey("tipoChamado"))
        {
            setTipoChamadoEnum((EnumTipoChamado) FacesContext.getCurrentInstance().getExternalContext().getFlash().get("tipoChamado"));
            setMsgPainelPrincipal("Atributos de Serviço de " + getTipoChamadoEnum().name());
            setExibirPainelNome(true);
            tabela = Modelo.getInstancia().gerarLazyModelAtributos(objetoEnum, ss);
        }

        if (objetoEnum == null && tipoChamadoEnum == null)
        {
            String message = "Erro na requisição. Use os menus de navegação para prevenir este erro.";
            FacesContext.getCurrentInstance().addMessage(null,
                    new FacesMessage(FacesMessage.SEVERITY_FATAL, message, null));
            return;
        }
    }

    /**
     * Encerra a sessão do hibernate na destruicao do bean.
     */
    @PreDestroy
    public void encerrar()
    {
        ss.close();
    }

    /**
     * Limpa o nome do atributo do bean.
     */
    public void limparBean()
    {
        setNomeAtributo("");
    }

    /**
     * Cria uma lista para montagem do combo de acordo com os valores do EnumTipoAtributo.
     * @return SelectItem[] = Lista para montagem de combo (SelectItem).
     */
    public Collection<SelectItem> getListaTiposAtributos()
    {
        return Modelo.getInstancia().getListaTiposAtributos();
    }

    /**
     * Adiciona o atributo informado na view e faz tratamento de erro.
     */
    public void adicionarAtributo()
    {
        try
        {
            AtributoValor atributo = new AtributoValor();

            atributo.setObjeto(objetoEnum);
            atributo.setNomeAtributo(getNomeAtributo());
            atributo.setTipo(getTipoAtributo());

            Modelo.getInstancia().adicionar(atributo, ss);

            limparBean();

            FacesContext.getCurrentInstance().addMessage("Mensagem", new FacesMessage(FacesMessage.SEVERITY_INFO,
                    "Atributo [" + atributo.getNomeAtributo() + "] adicionado com sucesso!", ""));

        }
        catch (ConstraintViolationException e)
        {
            FacesContext.getCurrentInstance().addMessage("Mensagem", new FacesMessage(FacesMessage.SEVERITY_WARN,
                    "Este atributo já está cadastrado!", ""));
            limparBean();
            ss.close();
            ss = HibernateUtil.getSessionFactory().openSession();

        }

    }

    /**
     * Remove o atributo selecionado da tabela na view e faz tratamento de erro.
     */
    public void excluirAtributo()
    {
        try
        {
            if (atributoSelecionado == null)
            {
                FacesContext.getCurrentInstance().addMessage("Mensagem", new FacesMessage(FacesMessage.SEVERITY_WARN,
                        "Selecione algum item antes de remover!", ""));
            }
            else
            {
                Modelo.getInstancia().remover(atributoSelecionado, ss);

                FacesContext.getCurrentInstance().addMessage("Mensagem", new FacesMessage(FacesMessage.SEVERITY_INFO,
                        "Atributo [" + atributoSelecionado.getNomeAtributo() + "] removido com sucesso!", ""));

            }
        }
        catch (Exception e)
        {
            FacesContext.getCurrentInstance().addMessage("Mensagem", new FacesMessage(FacesMessage.SEVERITY_FATAL,
                    "Erro ao remover: " + e.getMessage(), ""));
        }
    }

    //Getters and Setters
    public boolean isExibirPainelNome()
    {
        return exibirPainelNome;
    }

    public void setExibirPainelNome(boolean exibirPainelNome)
    {
        this.exibirPainelNome = exibirPainelNome;
    }

    public String getMsgPainelPrincipal()
    {
        return msgPainelPrincipal;
    }

    public void setMsgPainelPrincipal(String msgPainelPrincipal)
    {
        this.msgPainelPrincipal = msgPainelPrincipal;
    }

    public EnumObjetosPersistentes getObjetoEnum()
    {
        return objetoEnum;
    }

    public EnumTipoChamado getTipoChamadoEnum()
    {
        return tipoChamadoEnum;
    }

    public void setTipoChamadoEnum(EnumTipoChamado tipoChamadoEnum)
    {
        this.tipoChamadoEnum = tipoChamadoEnum;
    }

    public void setObjetoEnum(EnumObjetosPersistentes objetoEnum)
    {
        this.objetoEnum = objetoEnum;
    }

    public String getNomeAtributo()
    {
        return nomeAtributo;
    }

    public void setNomeAtributo(String nomeAtributo)
    {
        this.nomeAtributo = nomeAtributo;
    }

    public EnumTipoAtributo getTipoAtributo()
    {
        return tipoAtributo;
    }

    public void setTipoAtributo(EnumTipoAtributo tipoAtributo)
    {
        this.tipoAtributo = tipoAtributo;
    }

    public AtributoValor getAtributoSelecionado()
    {
        return atributoSelecionado;
    }

    public void setAtributoSelecionado(AtributoValor atributoSelecionado)
    {
        this.atributoSelecionado = atributoSelecionado;
    }

    public LazyDataModel<AtributoValor> getTabela()
    {
        return tabela;
    }

    public void setTabela(LazyDataModel<AtributoValor> tabela)
    {
        this.tabela = tabela;
    }
}
